import {
  CSSProperties,
  FC,
  ReactNode,
  useCallback,
  useEffect,
  useRef,
  useState,
} from 'react'
import { useColorVar, useStyles } from '@/hooks/styles'
import styles from './MethodCard.module.scss'
import { SvgIcon } from '@/components/icons'
import { More } from '@/components/icons/More'
import { Button } from 'antd'
import { Start } from '@/components/icons/Start'
import { Graph, Node } from '@antv/x6'
import { debounce } from 'lodash'
import { PortManager } from '@antv/x6/lib/model/port'
import PortMetadata = PortManager.PortMetadata
import { useMetaStore, useWtsStore } from '@/hooks'

interface IMethodCard {
  width?: CSSProperties['width']
  // header部分
  cardIcon?: ReactNode
  cardTitle?: string
  tag?: ReactNode

  input?: ReactNode
  output?: ReactNode

  isButtonDisabled: boolean
  onClick: () => void

  style?: CSSProperties
  className?: string
  // children?: ReactNode | null
  node?: Node
  graph?: Graph
  // cardID?: UUID
  // cardIndex?: number
  // designMethod?: DesignMethod
}

export const MethodCard: FC<IMethodCard> = ({
  width,

  cardIcon,
  cardTitle,
  tag,

  input,
  output,
  style,
  className,
  isButtonDisabled,
  onClick,
  children,
  node,
  // cardID,
  // cardIndex,
  // designMethod,
}) => {
  const c = useColorVar()
  const styleClass = useStyles(styles)
  const sizeRef = useRef()
  const metaStore = useMetaStore()
  const wtsStore = useWtsStore()

  const [portsPosition, setPortsPosition] = useState<[number, number][]>([])

  const handleCardResizeDebounce = useCallback(
    debounce(
      (width: number, height: number, cardDOM: HTMLElement) => {
        // 更新节点大小
        node.prop('size', { width: width, height: height })

        const elements = cardDOM.querySelectorAll('#port-circle')
        if (elements.length > portsPosition.length) {
          const { left: baseLeft, top: baseTop } =
            cardDOM.getBoundingClientRect()
          const newPortsPosition = [...portsPosition]
          for (let i = portsPosition.length; i < elements.length; i++) {
            const { left, top } = elements[i].getBoundingClientRect()
            newPortsPosition.push([left - baseLeft, top - baseTop])
          }
          setPortsPosition(newPortsPosition)
        }
      },
      100,
      { leading: true, trailing: true, maxWait: 1000 }
    ),
    []
  )

  const calcPorts = (node: Node, portsPosition: [number, number][]) => {
    const currentPorts = node.getPorts()
    const ports: PortMetadata[] = []
    for (let i = currentPorts.length; i < portsPosition.length; i++) {
      ports.push({
        id: `${node.id}-${i + 1}`,
        group: portsPosition[i][0] < 100 ? 'absolute_in' : 'absolute_out',
        args: {
          x: portsPosition[i][0],
          y: portsPosition[i][1],
        },
      })
    }

    node.addPorts(ports)
  }

  useEffect(() => {
    node && calcPorts(node, portsPosition)
  }, [portsPosition])

  useEffect(() => {
    const cardDOM = sizeRef.current as HTMLElement
    const resizeObserver = new ResizeObserver((entries) => {
      handleCardResizeDebounce(
        entries[0].target.clientWidth,
        entries[0].target.clientHeight,
        cardDOM
      )
    })

    node && resizeObserver.observe(cardDOM)

    return () => resizeObserver.unobserve(cardDOM)
  }, [])

  return (
    <div
      ref={sizeRef}
      {...styleClass(
        ['layout'],
        {
          width: width,
          boxShadow: node
            ? '0 4px 16px 0 rgba(10, 20, 69, 0.08)'
            : '0 4px 10px 0 rgba(10, 20, 69, 0.025)',
        },
        { style, className }
      )}
    >
      <div {...styleClass(['header'])}>
        <div {...styleClass(['header-prefix'])}>
          {cardIcon}
          <div {...styleClass(['header-prefix-text'])}>{cardTitle}</div>
          {tag}
        </div>

        <div {...styleClass(['header-suffix'])}>
          <Button
            {...styleClass(['header-suffix-button'])}
            type={'primary'}
            size={'small'}
            disabled={isButtonDisabled}
            onClick={onClick}
          >
            {/* TODO: move onClick elsewhere  */}
            <SvgIcon icon={Start} />
          </Button>
          <div {...styleClass(['header-suffix-more'])}>
            <SvgIcon icon={More} />
          </div>
        </div>
      </div>
      <div {...styleClass(['content'])}>
        {children}
        <div {...styleClass(['content-part'])}>
          <div {...styleClass(['content-part-title'])}>
            <div {...styleClass(['content-part-title-text'])}>输入</div>
          </div>
          {input}
        </div>

        <div {...styleClass(['content-part'])}>
          <div {...styleClass(['content-part-title'])}>
            <div {...styleClass(['content-part-title-text'])}>输出</div>
          </div>
          {output}
        </div>
      </div>
    </div>
  )
}
